package org.example.demo1.service;


import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.client.*;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.demo1.config.MonitorConfig;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class PodService {

    private static final String KUBECONFIG_PATH = "E:\\whu-ops\\src\\main\\resources\\templates\\config";
    private final MonitorConfig monitorConfig;

    /**
     * 获取Pod详细状态（kubectl风格）
     */
    public List<Map<String, Object>> getK8sPodsDetail() {
        try (KubernetesClient client = getClient()) {
            String namespace = client.getNamespace();
            // 关键修复：若namespace为空，则获取所有命名空间的Pod
            List<Pod> pods = (namespace == null || namespace.isEmpty())
                    ? client.pods().inAnyNamespace().list().getItems()
                    : client.pods().inNamespace(namespace).list().getItems();

            log.info("成功获取 {} 个Pod，命名空间: {}", pods.size(),
                    (namespace == null) ? "所有命名空间" : namespace);

            List<Map<String, Object>> result = new ArrayList<>();
            for (Pod pod : pods) {
                String podName = getPodName(pod);
                String podNamespace = getPodNamespace(pod);
                String phase = getPodPhase(pod);

                // 获取kubectl风格的状态
                String displayStatus = getKubectlStatus(pod);


                result.add(Map.of(
                        "name", podName,
                        "namespace", podNamespace,
                        "phase", phase,
                        "displayStatus", displayStatus // kubectl显示的状态
                ));
            }
            return result;
        } catch (Exception e) {
            log.error("获取Kubernetes Pod详细信息失败", e);
            throw new RuntimeException("获取Kubernetes Pod详细信息失败", e);
        }
    }

    /**
     * 完整的kubectl风格状态获取方法
     */
    private String getKubectlStatus(Pod pod) {
        PodStatus status = pod.getStatus();
        String phase = status.getPhase();

        // 1. 首先检查是否正在删除
        if (pod.getMetadata().getDeletionTimestamp() != null) {
            return "Terminating";
        }

        // 2. 检查初始化容器状态
        List<ContainerStatus> initContainerStatuses = status.getInitContainerStatuses();
        if (initContainerStatuses != null && !initContainerStatuses.isEmpty()) {
            for (int i = 0; i < initContainerStatuses.size(); i++) {
                ContainerStatus cs = initContainerStatuses.get(i);

                if (cs.getState().getWaiting() != null) {
                    String reason = cs.getState().getWaiting().getReason();
                    return "Init:" + reason;
                }

                if (cs.getState().getTerminated() != null) {
                    if (cs.getState().getTerminated().getExitCode() != 0) {
                        return "Init:Error";
                    }
                }

                if (cs.getState().getRunning() != null) {
                    return "Init:" + (i + 1) + "/" + initContainerStatuses.size();
                }
            }
        }

        // 3. 检查主容器状态
        List<ContainerStatus> containerStatuses = status.getContainerStatuses();
        if (containerStatuses != null && !containerStatuses.isEmpty()) {
            int readyCount = 0;
            int totalCount = containerStatuses.size();

            for (ContainerStatus cs : containerStatuses) {
                if (cs.getReady()) {
                    readyCount++;
                }

                // 检查容器等待状态
                if (cs.getState().getWaiting() != null) {
                    String reason = cs.getState().getWaiting().getReason();
                    switch (reason) {
                        case "ImagePullBackOff":
                        case "ErrImagePull":
                            return "ImagePullBackOff";
                        case "CrashLoopBackOff":
                            return "CrashLoopBackOff";
                        case "ContainerCreating":
                            return "ContainerCreating";
                        case "CreateContainerConfigError":
                            return "CreateContainerConfigError";
                        case "InvalidImageName":
                            return "InvalidImageName";
                        default:
                            return reason;
                    }
                }

                // 检查容器终止状态
                if (cs.getState().getTerminated() != null) {
                    String reason = cs.getState().getTerminated().getReason();
                    int exitCode = cs.getState().getTerminated().getExitCode();

                    if ("OOMKilled".equals(reason)) {
                        return "OOMKilled";
                    } else if (exitCode != 0) {
                        return "Error";
                    }
                }
            }

            // 4. 基于Phase和容器就绪情况返回状态
            switch (phase) {
                case "Pending":
                    return "Pending";
                case "Running":
                    if (readyCount == totalCount) {
                        return "Running";
                    } else {
                        return readyCount + "/" + totalCount;
                    }
                case "Succeeded":
                    return "Completed";
                case "Failed":
                    return "Failed";
                case "Unknown":
                    return "Unknown";
                default:
                    return phase;
            }
        }

        return phase;
    }

    /**
     * 获取Pod详情
     */
    public Map<String, Object> describePod(String podName, String namespace) {
        try (KubernetesClient client = getK8sClient()) {
            String targetNamespace = namespace;

            Pod pod = client.pods().inNamespace(targetNamespace).withName(podName).get();
            if (pod == null) {
                throw new RuntimeException("Pod不存在: " + podName);
            }

            Map<String, Object> result = new HashMap<>();
            result.put("metadata", pod.getMetadata());
            result.put("spec", pod.getSpec());
            result.put("status", pod.getStatus());

            return result;
        } catch (Exception e) {
            log.error("获取Pod详情失败", e);
            throw new RuntimeException("获取Pod详情失败: " + e.getMessage(), e);
        }
    }

    /**
     * 重启Pod（通过删除Pod让Deployment重新创建）
     */
    public Map<String, Object> restartPod(String podName, String namespace) {
        try (KubernetesClient client = getClient()) {
            String targetNamespace = client.getNamespace();

            List<StatusDetails> deletedResult = client.pods().inNamespace(targetNamespace).withName(podName).delete();

            //判断返回的列表是不是空 不空则删除成功
            boolean deleted=deletedResult!=null&&!deletedResult.isEmpty();

            Map<String, Object> result = new HashMap<>();
            result.put("success", deleted);
            result.put("message", deleted ? "Pod删除成功，Deployment将自动重新创建" : "Pod删除失败");
            result.put("podName", podName);
            result.put("namespace", targetNamespace);

            return result;
        } catch (Exception e) {
            log.error("重启Pod失败", e);
            throw new RuntimeException("重启Pod失败: " + e.getMessage(), e);
        }
    }

    /**
     * 删除Pod
     */
    public Map<String, Object> deletePod(String podName, String namespace) {
        try (KubernetesClient client = getClient()) {
            String targetNamespace = client.getNamespace();

            List<StatusDetails> deletedResult = client.pods().inNamespace(targetNamespace).withName(podName).delete();

            //判断返回的列表是不是空 不空则删除成功
            boolean deleted=deletedResult!=null&&!deletedResult.isEmpty();
            Map<String, Object> result = new HashMap<>();
            result.put("success", deleted);
            result.put("message", deleted ? "Pod删除成功" : "Pod删除失败");
            result.put("podName", podName);
            result.put("namespace", targetNamespace);

            return result;
        } catch (Exception e) {
            log.error("删除Pod失败", e);
            throw new RuntimeException("删除Pod失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取Pod日志（支持指定命名空间和容器）
     */
    public  String getPodLogs(String podName, String namespace, String container) {
        try (KubernetesClient client = getK8sClient()) {
            String targetNamespace = namespace;

            log.info("正在获取Pod {} 的日志，命名空间: {}, 容器: {}", podName, targetNamespace, container);

            String logs;

            // 根据是否指定容器来选择不同的调用方式
            if (container != null && !container.isEmpty()) {
                // 指定容器的情况
                logs = client.pods()
                        .inNamespace(targetNamespace)
                        .withName(podName)
                        .inContainer(container)  // 这里返回ContainerResource
                        .getLog(true);           // ContainerResource的getLog方法
            } else {
                // 不指定容器的情况
                logs = client.pods()
                        .inNamespace(targetNamespace)
                        .withName(podName)
                        .getLog(true);           // PodResource的getLog方法
            }

            if (logs == null || logs.isEmpty()) {
                log.warn("Pod {} 没有日志", podName);
                return "没有日志";
            }

            log.info("成功获取Pod {} 的日志", podName);
            return logs;
        } catch (Exception e) {
            log.error("获取Pod {} 的日志失败: {}", podName, e.getMessage(), e);
            throw new RuntimeException("获取Pod日志失败: " + e.getMessage());
        }
    }


    // 辅助方法
    private String getPodName(Pod pod) {
        return pod.getMetadata().getName();
    }

    private String getPodNamespace(Pod pod) {
        return pod.getMetadata().getNamespace();
    }

    private String getPodPhase(Pod pod) {
        return pod.getStatus().getPhase();
    }

    public List<Map<String, Object>> getK8sNodesDetail() {
        try (KubernetesClient client = getClient()) {
            List<io.fabric8.kubernetes.api.model.Node> nodes = client.nodes().list().getItems();

            List<Map<String, Object>> result = new ArrayList<>();
            for (io.fabric8.kubernetes.api.model.Node node : nodes) {
                String nodeName = node.getMetadata().getName();
                String status = "normal";
                String message = "节点运行正常";

                // 检查节点状态
                List<NodeCondition> conditions = node.getStatus().getConditions();
                for (NodeCondition condition : conditions) {
                    if ("Ready".equals(condition.getType())) {
                        if (!"True".equals(condition.getStatus())) {
                            status = "abnormal";
                            message = "节点未就绪: " + condition.getMessage();
                        }
                        break;
                    }
                }

                result.add(Map.of(
                        "name", nodeName,
                        "status", status,
                        "message", message
                ));
            }
            return result;
        } catch (Exception e) {
            log.error("获取Kubernetes节点详细信息失败", e);
            throw new RuntimeException("获取Kubernetes节点详细信息失败", e);
        }
    }


    public KubernetesClient getClient() throws IOException {

        // 查找 kubeconfig 文件
        return new DefaultKubernetesClient(Config.fromKubeconfig(Files.readString(new File(KUBECONFIG_PATH).toPath())));
    }

    private KubernetesClient getK8sClient() {
        Config config = new ConfigBuilder()
                .withMasterUrl(monitorConfig.getKubernetes().getMasterUrl())
                .withOauthToken(monitorConfig.getKubernetes().getToken())
                .withTrustCerts(true)
                .build();
        return new KubernetesClientBuilder().withConfig(config).build();
    }

}
